package com.jia.train.seat.service.impl;

import cn.hutool.core.date.DateTime;
import com.jia.train.global.context.AuthContextHolder;
import com.jia.train.global.response.BaseResponse;
import com.jia.train.seat.entity.ConfirmOrder;
import com.jia.train.seat.entity.DailyTrainSeat;
import com.jia.train.seat.entity.DailyTrainTicket;
import com.jia.train.seat.enums.ConfirmOrderStatusEnum;
import com.jia.train.seat.feign.TrainMemberFeignClient;
import com.jia.train.seat.feign.pojo.TicketSaveRequest;
import com.jia.train.seat.feign.pojo.TicketSaveResponse;
import com.jia.train.seat.mapper.ConfirmOrderMapper;
import com.jia.train.seat.mapper.DailyTrainSeatMapper;
import com.jia.train.seat.mapper.DailyTrainSeatMapperCust;
import com.jia.train.seat.request.ConfirmOrderTicketRequest;
import com.jia.train.seat.service.AfterConfirmOrderService;
import io.seata.core.context.RootContext;
import io.seata.spring.annotation.GlobalTransactional;
import jakarta.annotation.Resource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

@Service
public class AfterConfirmOrderServiceImpl implements AfterConfirmOrderService {

    public static final Logger logger = LoggerFactory.getLogger(AfterConfirmOrderServiceImpl.class);

    @Resource
    private DailyTrainSeatMapper dailyTrainSeatMapper;

    @Resource
    private DailyTrainSeatMapperCust dailyTrainTicketMapperCust;

    @Resource
    private ConfirmOrderMapper confirmOrderMapper;

    @Resource
    private TrainMemberFeignClient trainMemberFeignClient;

    @Override
    @GlobalTransactional
    public void afterDoConfirmOrder(DailyTrainTicket dailyTrainTicket,
                                    List<DailyTrainSeat> finalSeatList,
                                    List<ConfirmOrderTicketRequest> tickets,
                                    ConfirmOrder confirmOrder) {
        logger.info("seat seata 全局事务ID：{}", RootContext.getXID());
        DateTime now = DateTime.now();
        // 更新座位
        for (DailyTrainSeat dailyTrainSeat : finalSeatList) {
            DailyTrainSeat conditionDailyTrainSeat = new DailyTrainSeat();
            conditionDailyTrainSeat.setId(dailyTrainSeat.getId());
            conditionDailyTrainSeat.setSell(dailyTrainSeat.getSell());
            conditionDailyTrainSeat.setUpdateTime(now);
            dailyTrainSeatMapper.updateByPrimaryKeySelective(conditionDailyTrainSeat);

            // 扣减库存
            int startIndex = dailyTrainTicket.getStartIndex().intValue();
            int endIndex = dailyTrainTicket.getEndIndex().intValue();

            char[] chars = conditionDailyTrainSeat.getSell().toCharArray();

            Integer maxStartIndex = endIndex - 1;
            Integer minEndIndex = startIndex + 1;

            int minStartIndex = 0;
            for (int i = startIndex - 1; i >= 0; i--) {
                char aChar = chars[i];
                if (aChar == '1') {
                    minStartIndex = i + 1;
                    break;
                }
            }

            logger.info("影响出发站区间{}-{}", minStartIndex, maxStartIndex);

            int maxEndIndex = conditionDailyTrainSeat.getSell().length();
            for (int i = endIndex; i < conditionDailyTrainSeat.getSell().length(); i++) {
                char aChar = chars[i];
                if (aChar == '1') {
                    maxEndIndex = i;
                    break;
                }
            }

            logger.info("影响到达站区间{}-{}", minEndIndex, maxEndIndex);

            dailyTrainTicketMapperCust.updateCountBySell(
                    dailyTrainSeat.getDate(),
                    dailyTrainSeat.getTripCode(),
                    dailyTrainSeat.getSeatType(),
                    minStartIndex,
                    maxStartIndex,
                    minEndIndex,
                    maxEndIndex
            );

        }

        // 增加会员票
        List<TicketSaveRequest> list = new ArrayList<>(finalSeatList.size());
        TicketSaveRequest ticketSaveRequest;
        for (int i = 0; i < tickets.size(); i++) {
            ticketSaveRequest = new TicketSaveRequest();
            // TODO Feign 怎么传递用户信息呢
            ticketSaveRequest.setMemberId(AuthContextHolder.getId());
            ticketSaveRequest.setPassengerId(tickets.get(i).getPassengerId());
            ticketSaveRequest.setPassengerName(tickets.get(i).getPassengerName());
            ticketSaveRequest.setTrainDate(dailyTrainTicket.getDate());
            ticketSaveRequest.setTripCode(dailyTrainTicket.getTripCode());

            ticketSaveRequest.setCarriageIndex(finalSeatList.get(i).getCarriageIndex());
            ticketSaveRequest.setSeatRow(finalSeatList.get(i).getRow());
            ticketSaveRequest.setSeatCol(finalSeatList.get(i).getCol());
            ticketSaveRequest.setSeatType(finalSeatList.get(i).getSeatType());

            ticketSaveRequest.setStartStation(dailyTrainTicket.getStart());
            ticketSaveRequest.setStartTime(dailyTrainTicket.getStartTime());
            ticketSaveRequest.setEndStation(dailyTrainTicket.getEnd());
            ticketSaveRequest.setEndTime(dailyTrainTicket.getEndTime());

            list.add(ticketSaveRequest);
        }

        logger.info("openFeign 远程调用Member接口 ");
        BaseResponse<List<TicketSaveResponse>> ticket = trainMemberFeignClient.createTicket(list);
        if (!ticket.isSuccess()) {
            throw new RuntimeException(String.format("远程调用Member接口失败：%s", ticket));
        }

//        if (1 == 1) {
//            throw new RuntimeException("主动模拟异常");
//        }

        // 更新订单
        ConfirmOrder conditionConfirmOrder = new ConfirmOrder();
        conditionConfirmOrder.setId(confirmOrder.getId());
        conditionConfirmOrder.setStatus(ConfirmOrderStatusEnum.SUCCESS.getCode());
        conditionConfirmOrder.setUpdateTime(now);
        confirmOrderMapper.updateByPrimaryKeySelective(conditionConfirmOrder);

    }


}

